package cn.ljw.interceptor;

import cn.ljw.common.RestResponse;
import cn.ljw.enums.ErrorCode;
import cn.ljw.exception.AlertException;
import cn.ljw.utils.BlogUtils;
import cn.ljw.utils.JwtUtils;
import io.jsonwebtoken.JwtException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * @author 一朝风月
 * @date 2024/3/27 19:28
 * @Code 面向注解面向卿，终无解释再无你
 * @description Jwt 授权过滤
 */
@Slf4j
@RequiredArgsConstructor
public class JwtAuthenticationFilter extends OncePerRequestFilter {
    //Security集成需要配置

    private final UserDetailsService userDetailsService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String jwtToken = BlogUtils.getJwtHeaderToken();
        if (StringUtils.hasText(jwtToken)) {
            String username;
            try {
                if (JwtUtils.isTokenExpired(jwtToken)) {
                    BlogUtils.writeJsonResponse(RestResponse.fail(ErrorCode.LOGIN_EXPIRE.getCode(), ErrorCode.LOGIN_EXPIRE.getMsg()), response);
                    return;
                }

                username = JwtUtils.getSubject(jwtToken);
            } catch (JwtException e) {
                log.error(e.getMessage(), e);
                BlogUtils.writeJsonResponse(RestResponse.fail(ErrorCode.NOT_LOGIN.getCode(), ErrorCode.NOT_LOGIN.getMsg()), response);
                return;
            }
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);
            if (null == userDetails) {
                throw new AlertException("用户不存在");
            }
            List<GrantedAuthority> authorities = AuthorityUtils.commaSeparatedStringToAuthorityList(JwtUtils.getRoles(jwtToken));

            UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(userDetails, null, authorities);
            SecurityContextHolder.getContext().setAuthentication(token);
        }

        filterChain.doFilter(request, response);
    }

}
